from core.context import Context
from core.models.api import APICode, APIResult
from core.models.types import CookieConfig, ProxyConfig
from fastapi import HTTPException, status, Request, APIRouter
from core.models.constants import (
    ERR_APP_CONTEXT_NONE,
    ERR_DOMAIN_EMPTY,
    ERR_COOKIES_EMPTY,
    ERR_APP_CONTEXT_NONE,
    ERR_DB_CONTEXT_NONE,
    ERR_DATA_SAVE,
    ERR_DATA_LOAD,
)

router = APIRouter()

@router.post("/cookies")
async def create_cookie_config(request: Request, config: CookieConfig):
    """
    创建Cookie配置对象。

    参数:
    config: CookieConfig - Cookie配置对象。

    返回值:
    CookieConfig: 创建后的Cookie配置对象。
    """

    domain = config.domain

    if not domain or domain == "":
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERR_DOMAIN_EMPTY)
    
    if not config.cookies or len(config.cookies) == 0:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=ERR_COOKIES_EMPTY)
    
    if request.app.state.ctx is None:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ERR_APP_CONTEXT_NONE,
        )
    ctx: Context = request.app.state.ctx

    if not ctx.db:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ERR_DB_CONTEXT_NONE,
        )
    
    cookie_config = ctx.db.load_data(CookieConfig, domain)
    if cookie_config is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=E)

    try:
        result = ctx.db.save_data(cookie_config, domain)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"{ERR_DATA_SAVE}: {e}")
    
    if result:
        return APIResult(code=APICode.Success, msg="ok")
    else:
        return APIResult(code=APICode.Failed, msg="failed")
    
@router.get("/cookies/{domain}")  
async def get_cookie_config(request: Request, domain: str):  
    """  
    获取指定域名的Cookie配置对象。  
  
    参数:  
    domain: str - 要获取Cookie配置的域名。
  
    返回值:  
    APIResult: 包含Cookie配置信息的响应对象。  
    """
    if not domain and domain == "":  
        raise HTTPException(  
            status_code=status.HTTP_400_BAD_REQUEST,  
            detail=ERR_DOMAIN_EMPTY  
        )
    
    if request.app.state.ctx is None:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_APP_CONTEXT_NONE,  
        )  
    ctx: Context = request.app.state.ctx  
  
    if not ctx.db:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_DB_CONTEXT_NONE,  
        )  
      
    cookie_config = ctx.db.load_data(CookieConfig, domain)  
    if cookie_config is None:  
        raise HTTPException(  
            status_code=status.HTTP_404_NOT_FOUND,  
            detail=f"Cookie config for domain '{domain}' not found"  
        )  
      
    # Assuming APIResult is a model you have to encapsulate your response  
    return APIResult(code=APICode.Success, msg="ok", data=cookie_config)

@router.delete("/cookies/{domain}")  
async def delete_cookie_config(request: Request, domain: str):
    """
    删除指定域名的Cookie配置对象。
    """
    if not domain and domain == "":  
        raise HTTPException(  
            status_code=status.HTTP_400_BAD_REQUEST,  
            detail=ERR_DOMAIN_EMPTY  
        )
    
    if request.app.state.ctx is None:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_APP_CONTEXT_NONE,  
        )  
    ctx: Context = request.app.state.ctx  
  
    if not ctx.db:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_DB_CONTEXT_NONE,  
        )
    
    try:
        result = ctx.db.remove_data(CookieConfig, domain)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"save data error: {e}")
    
    if result:
        return APIResult(code=APICode.Success, msg="ok")
    else:
        return APIResult(code=APICode.Failed, msg="failed")
    
@router.post("/proxy")
async def create_proxy_config(request: Request, config: ProxyConfig):
    if not config.proxys or len(config.proxys) == 0:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail="proxys不能为空")
    
    if request.app.state.ctx is None:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ERR_APP_CONTEXT_NONE,
        )
    ctx: Context = request.app.state.ctx

    if not ctx.db:
        raise HTTPException(
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
            detail=ERR_APP_CONTEXT_NONE,
        )
    
    proxy_config = ctx.db.load_data(ProxyConfig)
    if proxy_config is not None:
        raise HTTPException(status_code=status.HTTP_400_BAD_REQUEST, detail=f"context invalid")

    try:
        result = ctx.db.save_data(proxy_config)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"save data error: {e}")
    
    if result:
        return APIResult(code=APICode.Success, msg="ok")
    else:
        return APIResult(code=APICode.Failed, msg="failed")
    
@router.get("/proxy")  
async def get_proxy_config(request: Request):  
    if request.app.state.ctx is None:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_APP_CONTEXT_NONE,  
        )  
    ctx: Context = request.app.state.ctx  
  
    if not ctx.db:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_DB_CONTEXT_NONE,  
        )  
    try:
        proxy_config = ctx.db.load_data(ProxyConfig)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=ERR_DATA_LOAD)  
    if proxy_config is None:  
        raise HTTPException(  
            status_code=status.HTTP_404_NOT_FOUND,  
            detail=f"Proxy config not found"  
        )  
      
    # Assuming APIResult is a model you have to encapsulate your response  
    return APIResult(code=0, msg="ok", data=proxy_config)

@router.delete("/proxy")  
async def delete_proxy_config(request: Request):
    """
    删除指定域名的Proxy配置对象。
    """
    if request.app.state.ctx is None:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_APP_CONTEXT_NONE,  
        )  
    ctx: Context = request.app.state.ctx  
  
    if not ctx.db:  
        raise HTTPException(  
            status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,  
            detail=ERR_DB_CONTEXT_NONE,  
        )
    
    try:
        result = ctx.db.remove_data(ProxyConfig)
    except Exception as e:
        raise HTTPException(status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, detail=f"save data error: {e}")
    
    if result:
        return APIResult(code=APICode.Success, msg="ok")
    else:
        return APIResult(code=APICode.Failed, msg="failed")
    